/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-02-27     liyih       the first version
 */
#include <AD9910/AD9910_RAM.hpp>
#include "AD9910_RAM.hpp"

AD9910_RAM::AD9910_RAM()
{
    this->module_init();
}

AD9910_RAM::~AD9910_RAM()
{
    // TODO 自动生成的析构函数存根
}

void AD9910_RAM::setDefaultCFR()
{
    CFR1 = {0xC0, 0x40, 0x00, 0x00}; // RAM回放目的：幅度; 反Sinc滤波器使能; 3线式串行编程模式
    CFR2 = {0x01, 0x00, 0x00, 0x00}; // 使能单频profile调制幅度
    CFR3 = {0x05, 0x0F, 0x41, 0x32}; // VC0 = 0b101(VCO5); ICP = 0b001(237uA); 输入分频器正常工作; REFCLK PLL使能; 分频模数 = 0b11001(25倍频); 40MHz输入 * 25倍频 = 1GHz主频
}

profile_t AD9910_RAM::genRamProfile(uint16_t addrStepRate,
                                    uint16_t endAddr,
                                    uint16_t startAddr,
                                    RAM_MODE ramMode)
{
    // addrStepRate :0x0001 ~ 0xFFFF
    addrStepRate = addrStepRate > 0xFFFF ? 0xFFFF : addrStepRate;
    addrStepRate = addrStepRate < 1 ? 1 : addrStepRate;
    // 0 <= startAddr <= endAddr <= 0x3FF
    startAddr = startAddr > 0x3FF ? 0x3FF : startAddr;
    endAddr = endAddr > 0x3FF ? 0x3FF : endAddr;
    endAddr = startAddr > endAddr ? startAddr : endAddr;
    uint8_t ramModeByte = static_cast<uint8_t>(ramMode);

    profile_t RAM_Profile(8, 0);
    RAM_Profile[0] = 0x00;                   // 63:56 开路
    RAM_Profile[1] = addrStepRate >> 8;      // 55:48 地址步进率[15:8]
    RAM_Profile[2] = addrStepRate & 0xff;    // 47:40 地址步进率[7:0]
    RAM_Profile[3] = endAddr >> 2;           // 39:32 波形结束地址[9:2]
    RAM_Profile[4] = (endAddr & 0x3) << 6;   // 31:30 波形结束地址[1:0]     30:24 开路
    RAM_Profile[5] = startAddr >> 2;         // 23:16 波形起始地址[9:2]
    RAM_Profile[6] = (startAddr & 0x3) << 6; // 15:14 波形起始地址[1:0]      13:8 开路
    RAM_Profile[7] = ramModeByte;            // 7:0 RAM模式she'zhishezhi

    return RAM_Profile;
}

void AD9910_RAM::setRAM_Enable(bool enable)
{
    if (enable)
    {
        CFR1[0] |= 0X80; // 使能RAM
    }
    else
    {
        CFR1[0] &= ~0X80; // 关闭RAM
    }
    spi_sendData(REG_CFR1, CFR1);
}

void AD9910_RAM::setProfileCtrlMode(uint8_t endProfile, bool continuous, bool enable)
{
    uint8_t ctrlBits = 0b0000;
    if (enable && endProfile != 0)
    {
        endProfile = endProfile > 7 ? 7 : endProfile;

        if (continuous)
        {
            ctrlBits |= 0b1000;
            ctrlBits |= endProfile - 1;
        }
        else
        {
            ctrlBits |= endProfile;
        }
    }
    // set CFR1[20:17]
    uint8_t setValue = (ctrlBits & 0b1111) << 1;
    CFR1[1] &= ~(0b1111 << 1);
    CFR1[1] |= setValue;

    spi_sendData(REG_CFR1, CFR1);
}

void AD9910_RAM::writeProfile(const profile_t &profile, const uint8_t profileIndex)
{
    const uint8_t index = profileIndex > 7 ? 7 : profileIndex;
    uint8_t profileReg;
    switch (index)
    {
    case 0:
        profileReg = REG_PROFILE_0;
        break;
    case 1:
        profileReg = REG_PROFILE_1;
        break;
    case 2:
        profileReg = REG_PROFILE_2;
        break;
    case 3:
        profileReg = REG_PROFILE_3;
        break;
    case 4:
        profileReg = REG_PROFILE_4;
        break;
    case 5:
        profileReg = REG_PROFILE_5;
        break;
    case 6:
        profileReg = REG_PROFILE_6;
        break;
    case 7:
        profileReg = REG_PROFILE_7;
        break;
    default:
        profileReg = REG_PROFILE_0;
        break;
    }

    spi_sendData(profileReg, profile);
}

void AD9910_RAM::writeRAM(const ram_data_t &dataVec)
{
    spi_sendRam(dataVec);
}

ram_data_t AD9910_RAM::readRAM()
{
    ram_data_t ret;
    spi_readRam(ret);
    return ret;
}
